home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / sos3-2.lha / src / knl / knl.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  31KB  |  988 lines

  1. /* --------------------------------------------------------------------------
  2.  * Copyright 1992 by Forschungszentrum Informatik (FZI)
  3.  *
  4.  * You can use and distribute this software under the terms of the licence
  5.  * you should have received along with this program.
  6.  * If not or if you want additional information, write to
  7.  * Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
  8.  * D-7500 Karlsruhe 1, Germany.
  9.  * --------------------------------------------------------------------------
  10.  */
  11. // **************************************************************************
  12. // Module knl                       16/06/89           Bernhard Schiefer (bs)
  13. //                                                   modified : 09/02/90 (ju)
  14. //                                                              09/08/90 (dt)
  15. // **************************************************************************
  16. // implements methods of classes: sos_Id, sos_Typed_id, sos_Object,
  17. //                                sos_Ordered_object, sos_Scalar_object
  18. //                                sos_String, sos_Type
  19. // **************************************************************************
  20.  
  21. // ==========================================================================
  22. // method implementations for the types of the kernel schema
  23. //
  24. // Tracing conventions:
  25. //    - no tracing: module initialization, external type conversions, 
  26. //              local offset handling, C++ classes (except for allocation)
  27. //    - knl_M        : generic conversions, container storage allocation,
  28. //              local_... methods
  29. //    - knl_H        : other methods
  30. // ==========================================================================
  31.  
  32. #include <string.h>
  33. #include <ctype.h>
  34. #include <libc.h>      // bcopy
  35.  
  36. #include "sys.h"
  37. #include "smg.h"
  38. #include "knl_err.h"
  39. #include "trc_knl.h"
  40. #include "mta_use.h"
  41. #include "knl_sos.h"
  42.  
  43.  
  44. // ==========================================================================
  45. // quasi constants, module initialization
  46. // ==========================================================================
  47.  
  48. EXPORT sos_Object   NO_OBJECT;
  49. LOCAL  sos_Typed_id NOTPID;
  50. LOCAL  sos_Id         NOID;
  51.  
  52. LOCAL struct knl_dummy_struct { knl_dummy_struct (); } knl_dummy;
  53.  
  54. knl_dummy_struct::knl_dummy_struct ()
  55. {  _knl_init_sos();    // needed for 'sos_Object::make'
  56.  
  57.    NOID      = sos_Id::make (sos_Container::make (0), 0);
  58.    NOTPID    = sos_Typed_id::make (NOID, NOID);
  59.    NO_OBJECT = sos_Object::make(NOTPID);
  60. }
  61.  
  62.  
  63. // ==========================================================================
  64. // local utility methods
  65. // ==========================================================================
  66.  
  67. // *************************************************************************
  68. LOCAL inline sos_Comp_result make_comp_result (int i)
  69. // *************************************************************************
  70. {  return (i > 0) ? CMP_GREATER
  71.           : (i < 0 ) ? CMP_LESS
  72.                  : CMP_EQUAL;
  73. }
  74.  
  75.  
  76. // ==========================================================================
  77. // string conversion operations for the external types of the kernel schema
  78. // ==========================================================================
  79.  
  80. sos_String make_string_from_sos_Int_object (sos_Object i)
  81. {  sos_String result
  82.         = smg_String (make_sos_Int (i)).make_String (TEMP_CONTAINER);
  83.    return result;
  84. }
  85.  
  86. sos_Object make_sos_Int_object_from_string (sos_String s)
  87. {  sos_Cstring s1 = s.make_Cstring();
  88.    char           *ptr;
  89.    long        l = strtol (s1, &ptr, 10);
  90.    sos_Object  result = (ptr != s1 AND ptr[0] == 0)
  91.                ? make_sos_Int_object (sos_Int (l))
  92.                : NO_OBJECT;
  93.    delete s1;
  94.    return result;
  95. }
  96.  
  97. sos_String make_string_from_sos_Char_object (sos_Object c)
  98. {  char  s [2];
  99.    s[0] = make_sos_Char (c);
  100.    s[1] = EOS;
  101.  
  102.    sos_String result = smg_String (s).make_String (TEMP_CONTAINER);
  103.    return result;
  104. }
  105.  
  106. sos_Object make_sos_Char_object_from_string (sos_String s)
  107. {  sos_Cstring s1 = s.make_Cstring();
  108.  
  109.    sos_Object  result = (strlen (s1) == 1) ? make_sos_Char_object (s1[0])
  110.                        : NO_OBJECT;
  111.    delete s1;
  112.    return result;
  113. }
  114.  
  115. sos_String make_string_from_sos_Pointer_object (sos_Object p)
  116. {  sos_Pointer p1 = make_sos_Pointer (p);
  117.    sos_String result
  118.         = smg_String ((sos_Int)p1, FALSE).make_String (TEMP_CONTAINER);
  119.    return result;
  120. }
  121.  
  122. sos_Object make_sos_Pointer_object_from_string (sos_String s)
  123. {  sos_Cstring s1 = s.make_Cstring();
  124.    char        *ptr;
  125.    long        l = strtol (s1, &ptr, 16);
  126.    sos_Object  result = (ptr != s1 AND ptr[0] == 0)
  127.                ? make_sos_Pointer_object (sos_Pointer (l))
  128.                : NO_OBJECT;
  129.    delete s1;
  130.    return result;
  131. }
  132.  
  133. sos_String make_string_from_sos_Offset_object (sos_Object o)
  134. {  sos_Offset o1 = make_sos_Offset (o);
  135.    sos_String result = smg_String (o1).make_String (TEMP_CONTAINER);
  136.    return result;
  137. }
  138.  
  139. sos_Object make_sos_Offset_object_from_string (sos_String s)
  140. {  sos_Cstring s1 = s.make_Cstring();
  141.    char        *ptr;
  142.    long           l = strtol (s1, &ptr, 10);
  143.  
  144.    sos_Object  result = (ptr != s1 AND ptr[0] == 0)
  145.                ? make_sos_Offset_object (sos_Offset (l))
  146.                : NO_OBJECT;
  147.    delete s1;
  148.    return result;
  149. }
  150.  
  151. sos_String make_string_from_sos_Container_object (sos_Object ct)
  152. {  sos_Container ct1 = make_sos_Container (ct);
  153.    sos_String result = smg_String (ct1).make_String (TEMP_CONTAINER);
  154.    return result;
  155. }
  156.  
  157. sos_Object make_sos_Container_object_from_string (sos_String s)
  158. {  sos_Cstring s1 = s.make_Cstring();
  159.    char *ptr;
  160.    long l = strtol (s1, &ptr, 10);
  161.  
  162.    sos_Object result
  163.            = (ptr != s1 AND ptr[0] == EOS)
  164.             ? make_sos_Container_object (sos_Container::make ((int) l))
  165.             : NO_OBJECT;
  166.    delete s1;
  167.    return result;
  168. }
  169.  
  170. sos_String make_string_from_sos_Cstring_object (sos_Object s)
  171. {  sos_String result
  172.           = smg_String (make_sos_Cstring (s)).make_String (TEMP_CONTAINER);
  173.    return result;
  174. }
  175.  
  176. sos_Object make_sos_Cstring_object_from_string (sos_String s)
  177. {  sos_Cstring s1 = s.make_Cstring();
  178.    sos_Object result = make_sos_Cstring_object (s1);
  179.    return result;
  180. }
  181.  
  182. sos_String make_string_from_sos_Id_object (sos_Object i)
  183. {  sos_Id     i1 = make_sos_Id (i);
  184.    smg_String s = smg_String("<") + (int)i.container()
  185.                   + "," + (int)i.offset() + ">";
  186.    sos_String result = s.make_String (TEMP_CONTAINER);
  187.    return result;
  188. }
  189.  
  190. sos_Object make_sos_Id_object_from_string (sos_String s)
  191. {  smg_String s1 = s;
  192.    int        ct, os, l;
  193.    sscanf (s1.make_Cstring (SMG_BORROW), "<%d,%d>%n", &ct, &os, &l);
  194.    sos_Object  result;
  195.    if (l = s1.length())
  196.       result = make_sos_Id_object
  197.           (sos_Id::make (sos_Container::make (ct), sos_Offset (os)));
  198.    else
  199.       result = NO_OBJECT;
  200.    return result;
  201. }
  202.  
  203.  
  204. // ==========================================================================
  205. // generic conversion operations for scalar types
  206. // ==========================================================================
  207.  
  208. // *************************************************************************
  209. void sos_extern_from_object (void  *addr,
  210.                  sos_Object o,
  211.                  void bcopy_to (void*,void*),
  212.                  sos_Id tp)
  213. // *************************************************************************
  214. {  T_PROC ("sos_extern_from_object");
  215.    TT (knl_M, T_ENTER);
  216.  
  217.    if (o.typed_id().get_tp() != tp)
  218.       err_raise (err_SYS, err_SOS_TYPE_ERROR, "sos_extern_from_object", FALSE);
  219.  
  220.    sos_Id id = o.typed_id().get_id();
  221.    bcopy_to (addr, &id);
  222.       
  223.    TT (knl_M, T_LEAVE);
  224. }
  225.  
  226.  
  227. // *************************************************************************
  228. sos_Scalar_object sos_object_from_extern (void *addr,
  229.                       void bcopy_from (void*,void*),
  230.                       sos_Id tp)
  231. // *************************************************************************
  232. {  T_PROC ("sos_object_from_extern");
  233.    TT (knl_M, T_ENTER);
  234.  
  235.    sos_Id id = NOID;
  236.    // assures that the mapping scalar value - id is a bijection;
  237.    // -> preserves equality and ordering.
  238.  
  239.    bcopy_from (addr, &id);
  240.    sos_Scalar_object obj = sos_Scalar_object::make (sos_Typed_id::make (id, tp));
  241.  
  242.    TT (knl_M, T_LEAVE);
  243.    return obj;
  244. }
  245.  
  246. // *************************************************************************
  247. sos_Int sos_Int_from_enum (sos_Object o, sos_Type et)
  248. // *************************************************************************
  249. {  T_PROC ("sos_Int_from_enum");
  250.    TT (knl_M, T_ENTER);
  251.  
  252. #ifdef BOOT
  253.    err_assert (FALSE, "sos_Int_from_enum:BOOT");
  254. #endif
  255.    if (NOT o.has_type (et))
  256.       err_raise (err_SYS, err_SOS_TYPE_ERROR, "sos_Int_from_enum", FALSE);
  257.  
  258.    sos_Int size = et.get_object_size();
  259.    sos_Id  id   = o.typed_id ().get_id();
  260.    sos_Int result;
  261.    if (size == 1)
  262.       result = *(sos_Char*)&id;
  263.    else
  264.    {  err_assert (size == 2, "sos_Int_from_enum:invalid size");
  265.       result = *(sos_Short*)&id;
  266.    }
  267.  
  268.    TT (knl_M, T_LEAVE);
  269.    return result;
  270. }
  271.  
  272. // *************************************************************************
  273. sos_Scalar_object sos_enum_from_sos_Int (sos_Int i, sos_Type et)
  274. // *************************************************************************
  275. {
  276.    T_PROC ("sos_enum_from_sos_Int");
  277.    TT (knl_M, T_ENTER);
  278.  
  279. #ifdef BOOT
  280.    err_assert (FALSE, "sos_enum_from_sos_Int:BOOT");
  281. #endif
  282.    sos_Int size = et.get_object_size();
  283.    sos_Id id;
  284.    if (size == 1)
  285.       *(sos_Char*)&id = i;
  286.    else
  287.    {  err_assert (size == 2, "sos_enum_from_sos_Int:invalid size");
  288.       *(sos_Short*)&id = i;
  289.    }
  290.    sos_Scalar_object result =
  291.       sos_Scalar_object::make (sos_Typed_id::make (id, et.typed_id().get_id()));
  292.  
  293.    TT (knl_M, T_LEAVE);
  294.    return result;
  295. }
  296.  
  297.  
  298. // ==========================================================================
  299. // handle container local references
  300. // ==========================================================================
  301.  
  302. // *************************************************************************
  303. sos_Typed_id sos_make_local_typed_id (sos_Offset os, sos_Container ct)
  304. // *************************************************************************
  305. {  if (os == 0) return NOTPID;
  306.    else
  307.    {  sos_Id id = sos_Id::make (ct, os);
  308.       return sos_Typed_id::make (id, id.get_type_id());
  309.    }
  310. };
  311.  
  312.  
  313. // *************************************************************************
  314. sos_Offset sos_local_offset (sos_Object o, sos_Container ct)
  315. // *************************************************************************
  316. {  sos_Offset os = o.typed_id().offset();
  317.    if (os != 0 AND o.container() != ct)
  318.       err_raise (err_SYS, err_SOS_INVALID_ASSIGNMENT_TO_LOCAL,
  319.                           "assignment to a component that is declared to be local", FALSE);
  320.    return os;
  321. };
  322.  
  323.  
  324. // ==========================================================================
  325. // C++ class / external type sos_Id
  326. // ==========================================================================
  327.  
  328. // *************************************************************************
  329. void sos_Id::set_type_id (sos_Id tp)
  330. // *************************************************************************
  331. {  union { sos_Id dummy;
  332.        char   c[SOS_ID_SIZE]; } u;
  333.  
  334.    bcopy_from_sos_Id (&tp, &u);
  335.    container().write (offset(), SOS_ID_SIZE, &u);
  336. }
  337.  
  338.  
  339. // *************************************************************************
  340. sos_Id sos_Id::get_type_id ()
  341. // *************************************************************************
  342. {  sos_Id tp;
  343.    union { sos_Id dummy;
  344.        char   c[SOS_ID_SIZE]; } u;
  345.  
  346.    container().read (offset(), SOS_ID_SIZE, &u);
  347.    bcopy_to_sos_Id (&tp, &u);
  348.  
  349.    return tp;
  350. }
  351.  
  352.  
  353. // ==========================================================================
  354. // C++ class / external type sos_Typed_id
  355. // ==========================================================================
  356.  
  357. // *************************************************************************
  358. sos_Typed_id sos_Typed_id::make (sos_Id id)
  359. // *************************************************************************
  360. {  return sos_Typed_id::make (id, id.get_type_id());
  361. };
  362.  
  363. // *************************************************************************
  364. sos_Typed_id sos_Typed_id::allocate (sos_Type tp, sos_Container ct)
  365. // *************************************************************************
  366. {  T_PROC ("sos_Typed_id::allocate");
  367.    TT (knl_M, T_ENTER; TI ((sos_Int) ct));
  368.  
  369. #if BOOT
  370.    err_assert (FALSE, "sos_Typed_id::allocate");
  371. #endif
  372.  
  373.    sos_Typed_id tpid = allocate (tp, ct, tp.get_object_size());
  374.  
  375.    TT (knl_M, T_LEAVE);
  376.    return tpid;
  377. }
  378.  
  379. // *************************************************************************
  380. sos_Typed_id sos_Typed_id::allocate (sos_Type       tp,
  381.                      sos_Container  ct,
  382.                      sos_Int        object_size)
  383. // *************************************************************************
  384. {
  385.    T_PROC ("sos_Typed_id::allocate");
  386.    TT (knl_M, T_ENTER; TI (tp.container()); TI (tp.offset());
  387.           TI ((sos_Int) ct); TI (object_size));
  388.  
  389.    sos_Offset os = ct.allocate (object_size);
  390.  
  391.    sos_Id id = sos_Id::make (ct, os);
  392.    sos_Id tp_id = tp.typed_id().get_id();
  393.    id.set_type_id (tp_id);
  394.    sos_Typed_id tpid = sos_Typed_id::make (id, tp_id);
  395.  
  396.    TT (knl_M, T_LEAVE; TI (os));
  397.    return tpid;
  398. }
  399.  
  400.  
  401. // ==========================================================================
  402. // class sos_Object
  403. // ==========================================================================
  404.  
  405. // *************************************************************************
  406. sos_Type sos_Object::type ()
  407. // *************************************************************************
  408. {
  409.    T_PROC ("sos_Object::type");
  410.    TT (knl_H, T_ENTER);
  411.  
  412.    sos_Id id = self.typed_id().get_tp ();
  413. #if BOOT
  414.    sos_Typed_id tpid = sos_Typed_id::make (id, _sos_Type_type);
  415. #else
  416.    sos_Typed_id tpid = sos_Typed_id::make (id);
  417. #endif
  418.    sos_Type t = sos_Type::make (tpid);
  419.    TT (knl_H, T_LEAVE);
  420.    return t;
  421. } // ** type **
  422.  
  423.  
  424. // *************************************************************************
  425. sos_Bool sos_Object::has_type (sos_Type tp)
  426. // *************************************************************************
  427. {
  428.    T_PROC ("sos_Object::has_type");
  429.    TT (knl_H, T_ENTER);
  430.  
  431.    sos_Bool b = (self.typed_id().get_tp() == tp.typed_id().get_id());
  432.  
  433.    TT (knl_H, T_LEAVE; TB(b));
  434.    return b;
  435. } // ** has_type **
  436.  
  437.  
  438. // *************************************************************************
  439. sos_Bool sos_Object::isa (sos_Type tp)
  440. // *************************************************************************
  441. {
  442.    T_PROC ("sos_Object::isa");
  443.    TT (knl_H, T_ENTER);
  444.  
  445.    sos_Bool b;
  446.    if (self.has_type (tp))
  447.       b = TRUE;
  448.    else
  449.    {
  450. #if BOOT
  451.       err_assert (FALSE, "isa");
  452. #endif
  453.       b = self.type().is_derived_from (tp);
  454.    }
  455.  
  456.    TT (knl_H, T_LEAVE; TB(b));
  457.    return b;
  458. } // ** isa **
  459.  
  460.  
  461. // *************************************************************************
  462. sos_Bool sos_Object::is_some (sos_Type tp)
  463. // *************************************************************************
  464. {
  465.    T_PROC ("sos_Object::is_some");
  466.    TT (knl_H, T_ENTER);
  467.  
  468. #if BOOT
  469.    err_assert (FALSE, "is_some");
  470. #endif
  471.  
  472.    sos_Bool b = self.type().is_derived_from_some (tp);
  473.  
  474.    TT (knl_H, T_LEAVE; TB(b));
  475.    return b;
  476. } // ** is_some **
  477.  
  478.  
  479. // *************************************************************************
  480. sos_Int sos_Object::size ()
  481. // *************************************************************************
  482. {
  483.    T_PROC ("sos_Object::size");
  484.    TT (knl_H, T_ENTER);
  485.  
  486.    sos_Int i = self.container().rounded (self._size());
  487.  
  488.    TT (knl_H, T_LEAVE; TI (i));
  489.    return i;
  490. } // ** size **
  491.  
  492.  
  493. // **************************************************************************
  494. sos_Bool sos_Object::is_value ()
  495. // **************************************************************************
  496. {
  497.    // value components are not supported in this version!
  498.  
  499.    T_PROC ("sos_Object::is_value");
  500.    TT (knl_H, T_ENTER);
  501.  
  502.    err_raise_not_implemented ("sos_Object::is_value");
  503.    sos_Offset o = self.offset(); // suppress compiler warnings
  504.  
  505.    TT (knl_H, T_LEAVE);
  506.    return FALSE;
  507. } // ** is_value **
  508.  
  509.  
  510. // *************************************************************************
  511. sos_Bool sos_Object::identical (sos_Object anobject)
  512. // *************************************************************************
  513. {  return self.typed_id() == anobject.typed_id();
  514. } // ** identical **
  515.  
  516.  
  517. // *************************************************************************
  518. sos_Bool sos_Object::operator== (sos_Object anobject)
  519. // *************************************************************************
  520. {  return self.typed_id() == anobject.typed_id();
  521. } // ** operator== **
  522.  
  523.  
  524. // *************************************************************************
  525. sos_Bool sos_Object::operator!= (sos_Object anobject)
  526. // *************************************************************************
  527. {  return self.typed_id() != anobject.typed_id();
  528. } // ** operator!= **
  529.  
  530.  
  531. // *************************************************************************
  532. sos_Bool sos_Object::like (sos_Object anobject)
  533. // *************************************************************************
  534. {  return anobject.equal (self, /*eq_kind*/ EQ_WEAK);
  535. } // ** like **
  536.  
  537.  
  538. // **************************************************************************
  539. sos_Comp_result sos_Object::compare_ids (sos_Object o)
  540. // **************************************************************************
  541. {  T_PROC ("sos_Object::compare_ids");
  542.    TT (knl_H, T_ENTER);
  543.  
  544.    sos_Typed_id tpid1 = self.typed_id();
  545.    sos_Typed_id tpid2 = o.typed_id();
  546.  
  547.    int cmp_val = tpid1.get_id().offset() - tpid2.get_id().offset();
  548.  
  549.    if (cmp_val EQ 0)
  550.    {  cmp_val = tpid1.get_id().container() - tpid2.get_id().container();
  551.  
  552.       if (cmp_val EQ 0)
  553.       {  cmp_val = tpid1.get_tp().offset() - tpid2.get_tp().offset();
  554.  
  555.      if (cmp_val EQ 0)
  556.         cmp_val = tpid1.get_tp().container() - tpid2.get_tp().container();
  557.       }
  558.    }
  559.    sos_Comp_result result = make_comp_result (cmp_val);
  560.  
  561.    TT (knl_H, T_LEAVE);
  562.    return result;
  563. }
  564.  
  565. // *************************************************************************
  566. void sos_Object::local_assign (sos_Object, sos_Object)
  567. // *************************************************************************
  568. {
  569.    T_PROC ("sos_Object::local_assign");
  570.    TT (knl_M, T_ENTER);
  571.  
  572.    // do nothing.
  573.    // note that the generated local_assign would copy
  574.    // the component 'type_id'
  575.  
  576.    TT (knl_M, T_LEAVE);
  577. } // ** local_assign **
  578.  
  579.  
  580. // *************************************************************************
  581. sos_Bool sos_Object::local_equal (sos_Object,sos_Object,sos_Eq_kind)
  582. // *************************************************************************
  583. {
  584.    T_PROC ("sos_Object::local_equal");
  585.    TT (knl_M, T_ENTER);
  586.  
  587.    sos_Bool result = TRUE;
  588.  
  589.    // note that the generated local_equal would compare
  590.    // the component 'type_id'
  591.  
  592.    TT (knl_M, T_LEAVE; TB(result));
  593.    return result;
  594. } // ** local_equal **
  595.  
  596.  
  597. // *************************************************************************
  598. sos_Int sos_Object::local_hash_value (sos_Object)
  599. // *************************************************************************
  600. {
  601.    T_PROC ("sos_Object::local_hash_value");
  602.    TT (knl_M, T_ENTER);
  603.  
  604.    sos_Int result = 0;
  605.  
  606.    TT (knl_M, T_LEAVE; TI (result));
  607.    return result;
  608. } // ** hash_value **
  609.  
  610.  
  611. // ==========================================================================
  612. // class sos_Ordered_object
  613. // ==========================================================================
  614.  
  615. // *************************************************************************
  616. sos_Bool sos_Ordered_object::operator< (sos_Ordered_object o)
  617. // *************************************************************************
  618. {  T_PROC ("sos_Scalar_object::operator<");
  619.    TT (knl_H, T_ENTER);
  620.  
  621.    sos_Bool result = (sos_Bool)(self.compare (o) == CMP_LESS);
  622.  
  623.    TT (knl_H, T_LEAVE);
  624.    return result;
  625. }
  626.  
  627.  
  628. // *************************************************************************
  629. sos_Bool sos_Ordered_object::operator<= (sos_Ordered_object o)
  630. // *************************************************************************
  631. {  T_PROC ("sos_Scalar_object::operator<=");
  632.    TT (knl_H, T_ENTER);
  633.  
  634.    sos_Bool result = (sos_Bool)(self.compare (o) != CMP_GREATER);
  635.  
  636.    TT (knl_H, T_LEAVE);
  637.    return result;
  638. }
  639.  
  640.  
  641. // *************************************************************************
  642. sos_Bool sos_Ordered_object::operator> (sos_Ordered_object o)
  643. // *************************************************************************
  644. {  T_PROC ("sos_Scalar_object::operator>");
  645.    TT (knl_H, T_ENTER);
  646.  
  647.    sos_Bool result = (sos_Bool)(self.compare (o) == CMP_GREATER);
  648.  
  649.    TT (knl_H, T_LEAVE);
  650.    return result;
  651. }
  652.  
  653. // *************************************************************************
  654. sos_Bool sos_Ordered_object::operator>= (sos_Ordered_object o)
  655. // *************************************************************************
  656. {  T_PROC ("sos_Scalar_object::operator>");
  657.    TT (knl_H, T_ENTER);
  658.  
  659.    sos_Bool result = (sos_Bool)(self.compare (o) != CMP_GREATER);
  660.  
  661.    TT (knl_H, T_LEAVE);
  662.    return result;
  663. }
  664.  
  665.  
  666. // ==========================================================================
  667. // class sos_Scalar_object
  668. // ==========================================================================
  669.  
  670. // *************************************************************************
  671. void sos_Scalar_object::local_initialize (sos_Scalar_object)
  672. // *************************************************************************
  673. {  T_PROC ("sos_Scalar_object::local_initialize");
  674.    TT (knl_M, T_ENTER);
  675.  
  676.    err_raise (err_USE, err_SOS_ILLEGAL_EXT_OP,
  677.                "sos_Scalar_object::local_initialize", FALSE);
  678.    TT (knl_M, T_LEAVE);
  679. }
  680.  
  681. // *************************************************************************
  682. void sos_Scalar_object::local_finalize (sos_Scalar_object)
  683. // *************************************************************************
  684. {  T_PROC ("sos_Scalar_object::local_finalize");
  685.    TT (knl_M, T_ENTER);
  686.  
  687.    err_raise (err_USE, err_SOS_ILLEGAL_EXT_OP,
  688.                "sos_Scalar_object::local_finalize", FALSE);
  689.    TT (knl_M, T_LEAVE);
  690. }
  691.  
  692. // *************************************************************************
  693. void sos_Scalar_object::local_assign (sos_Scalar_object, sos_Object)
  694. // *************************************************************************
  695. {  T_PROC ("sos_Scalar_object::local_assign");
  696.    TT (knl_M, T_ENTER);
  697.  
  698.    err_raise (err_USE, err_SOS_ILLEGAL_EXT_OP,
  699.                "sos_Scalar_object::local_assign", FALSE);
  700.    TT (knl_M, T_LEAVE);
  701. }
  702.  
  703. // *************************************************************************
  704. sos_Bool sos_Scalar_object::local_equal (sos_Scalar_object x,
  705.                          sos_Object        o,
  706.                          sos_Eq_kind          )
  707. // *************************************************************************
  708. {  T_PROC ("sos_Scalar_object::local_equal");
  709.    TT (knl_M, T_ENTER);
  710.  
  711.    sos_Bool result = x.identical (o);
  712.  
  713.    TT (knl_M, T_LEAVE);
  714.    return result;
  715. }
  716.  
  717. // *************************************************************************
  718. sos_Int sos_Scalar_object::local_hash_value (sos_Scalar_object scalo)
  719. // *************************************************************************
  720. {  T_PROC ("sos_Scalar_object::local_hash_value");
  721.    TT (knl_M, T_ENTER);
  722.  
  723.    sos_Int result = scalo.offset();
  724.  
  725.    TT (knl_M, T_LEAVE);
  726.    return result;
  727. }
  728.  
  729.  
  730. // ==========================================================================
  731. // class sos_String
  732. // ==========================================================================
  733.  
  734. // *************************************************************************
  735. void sos_String::operator+= (sos_String s)
  736. // *************************************************************************
  737. {  T_PROC ("sos_String::operator+=");
  738.    TT (knl_H, T_ENTER);
  739.  
  740.    smg_String cat = smg_String (self) + s;
  741.    self.assign_Cstring (cat.make_Cstring (SMG_BORROW));
  742.  
  743.    TT (knl_H, T_LEAVE);
  744. }
  745.  
  746.  
  747. // *************************************************************************
  748. void sos_String::assign_Cstring (sos_Cstring s)
  749. // *************************************************************************
  750. {  T_PROC ("sos_String::assign_Cstring");
  751.    TT (knl_H, T_ENTER);
  752.  
  753.    sos_Int       size = strlen (s),
  754.          old_size = self.get_length();
  755.    sos_Container ct = self.container();
  756.  
  757.    if (old_size != size)
  758.    {  self.set_length (size);
  759.       if (old_size > 0)              // remove the old contents
  760.      ct.deallocate (self.get_address(), old_size);
  761.    }
  762.  
  763.    if (size > 0)
  764.    {  sos_Offset new_addr;
  765.  
  766.       if (old_size == size)      // it's not necessary to allocate new space
  767.          new_addr = self.get_address();
  768.       else
  769.       {  new_addr = ct.allocate (size);
  770.          self.set_address (new_addr);
  771.       }  
  772.       ct.write (new_addr, size, s);
  773.    }
  774.  
  775.    TT (knl_H, T_LEAVE; TI (old_size); TI (size));
  776. }
  777.  
  778.  
  779. // *************************************************************************
  780. sos_Cstring sos_String::make_Cstring ()
  781. // *************************************************************************
  782. {  T_PROC ("sos_String::make_Cstring");
  783.    TT (knl_H, T_ENTER);
  784.  
  785.    sos_Int     size = self.get_length();
  786.    sos_Cstring s = new char[size+1];
  787.  
  788.    self.container().read (self.get_address(), size, s);
  789.    s[size] = '\0';
  790.  
  791.    TT (knl_H, T_LEAVE; TI (size));
  792.    return s;
  793. }
  794.  
  795. // **************************************************************************
  796. sos_Int sos_String::size()
  797. // **************************************************************************
  798. {  T_PROC ("sos_String::size");
  799.    TT (knl_H, T_ENTER);
  800.  
  801.    sos_Int sz = self.container().rounded (self.get_length()) +
  802.                       sos_Object::size();
  803.    TT (knl_H, T_LEAVE);
  804.    return sz;
  805. }
  806.  
  807. // **************************************************************************
  808. sos_Comp_result sos_String::compare (sos_Ordered_object o)
  809. // **************************************************************************
  810. {  T_PROC ("sos_String::compare");
  811.    TT (knl_H, T_ENTER);
  812.  
  813.    if (NOT o.isa (sos_String_type))
  814.       err_raise (err_SYS, err_SOS_TYPE_ERROR, "sos_String::compare", FALSE);
  815.  
  816.    smg_String s1 = self;
  817.    smg_String s2 = sos_String::make (o);
  818.  
  819.    sos_Comp_result result = make_comp_result (s1.compare (s2));
  820.  
  821.    TT (knl_H, T_LEAVE);
  822.    return result;
  823. }
  824.  
  825. // *************************************************************************
  826. void sos_String::local_initialize (sos_String str)
  827. // *************************************************************************
  828. {  T_PROC ("sos_String::local_initialize");
  829.    TT (knl_M, T_ENTER);
  830.  
  831.    str.set_length (0);
  832.  
  833.    TT (knl_M, T_LEAVE);
  834. }
  835.  
  836. // *************************************************************************
  837. void sos_String::local_finalize (sos_String str)
  838. // *************************************************************************
  839. {  T_PROC ("sos_String::local_finalize");
  840.    TT (knl_M, T_ENTER);
  841.  
  842.    sos_Int size = str.get_length();
  843.  
  844.    if (size > 0)
  845.       str.container().deallocate (str.get_address(), size);
  846.  
  847.    TT (knl_M, T_LEAVE);
  848. }
  849.  
  850. // *************************************************************************
  851. void sos_String::local_assign (sos_String x, sos_Object o)
  852. // *************************************************************************
  853. {  T_PROC ("sos_String::local_assign");
  854.    TT (knl_M, T_ENTER);
  855.  
  856.    smg_String ostring = sos_String::make (o);
  857.    x.assign_Cstring (ostring.make_Cstring (SMG_BORROW));
  858.  
  859.    TT (knl_M, T_LEAVE);
  860. }
  861.  
  862. // *************************************************************************
  863. sos_Bool sos_String::local_equal (sos_String  x,
  864.                   sos_Object  o,
  865.                   sos_Eq_kind eq_kind)
  866. // *************************************************************************
  867. {  T_PROC ("sos_String::local_equal");
  868.    TT (knl_M, T_ENTER);
  869.  
  870.    sos_Bool result;
  871.  
  872.    if ((eq_kind EQ EQ_STRONG AND NOT o.has_type (sos_String_type)) OR
  873.        (eq_kind EQ EQ_WEAK   AND NOT o.isa      (sos_String_type)))
  874.       result = FALSE;
  875.    else
  876.    {  sos_String y   = sos_String::make (o);
  877.       sos_Int    l_y = y.get_length();
  878.  
  879.       result = (sos_Bool)(x.get_length() == l_y AND
  880.               x.container().equal(x.get_address(), l_y,
  881.                           y.container(), y.get_address()));
  882.    }
  883.  
  884.    TT (knl_M, T_LEAVE; TB(result));
  885.    return result;
  886. }
  887.  
  888. // *************************************************************************
  889. sos_Int sos_String::local_hash_value (sos_String x)
  890. // *************************************************************************
  891. {  T_PROC ("sos_String::local_hash_value");
  892.    TT (knl_M, T_ENTER);
  893.  
  894.    sos_Int result = x.container().hash_value (x.get_address(), x.get_length());
  895.  
  896.    TT (knl_M, T_LEAVE; TI (result));
  897.    return result;
  898. }
  899.  
  900.  
  901. // ==========================================================================
  902. // class sos_Type
  903. // ==========================================================================
  904.  
  905. // *************************************************************************
  906. sos_Type sos_type_object (sos_Id id, sos_Id tp)
  907. // *************************************************************************
  908. {
  909. #if BOOT
  910.    sos_Typed_id tpid = sos_Typed_id::make (id, _sos_Type_type);
  911. #else
  912.    sos_Typed_id tpid = sos_Typed_id::make (id, tp);
  913. #endif
  914.  
  915.    return sos_Type::make (tpid);
  916. } // ** sos_type_object **
  917.  
  918.  
  919. // *************************************************************************
  920. sos_Bool sos_Type::is_derived_from (sos_Type tp)
  921. // *************************************************************************
  922. {
  923.    T_PROC ("sos_Type::is_derived_from");
  924.    TT (knl_H, T_ENTER);
  925.  
  926.    sos_Bool result = self.equal (tp);
  927.  
  928.    TT (knl_H, T_LEAVE; TB (result));
  929.  
  930.    return result;
  931. }
  932.  
  933. // *************************************************************************
  934. sos_Bool sos_Type::is_derived_from_some (sos_Type tp)
  935. // *************************************************************************
  936. {
  937.    T_PROC ("sos_Type::is_derived_from_some");
  938.    TT (knl_H, T_ENTER);
  939.  
  940.    sos_Bool result = self.equal (tp);
  941.  
  942.    TT (knl_H, T_LEAVE; TB (result));
  943.  
  944.    return result;
  945. }
  946.  
  947. // *************************************************************************
  948. sos_Bool sos_Type::is_scalar ()
  949. // *************************************************************************
  950. {
  951.    T_PROC ("sos_Type::is_scalar");
  952.    TT (knl_H, T_ENTER);
  953.  
  954.    sos_Bool result = FALSE;   // Default-Implementation.
  955.                               // This method is redefined in
  956.                               // class sos_Scalar_type!
  957.    TT (knl_H, T_LEAVE; TB (result));
  958.    return result;
  959. }
  960.  
  961. // *************************************************************************
  962. sos_Type sos_Type::base ()
  963. // *************************************************************************
  964. {
  965.    T_PROC ("sos_Type::base");
  966.    TT (knl_H, T_ENTER);
  967.  
  968.    sos_Type t = self;
  969.  
  970.    TT (knl_H, T_LEAVE);
  971.  
  972.    return t;
  973. }
  974.  
  975. // *************************************************************************
  976. sos_Type sos_Type::root ()
  977. // *************************************************************************
  978. {
  979.    T_PROC ("sos_Type::root");
  980.    TT (knl_H, T_ENTER);
  981.  
  982.    sos_Type t = self.base();
  983.  
  984.    TT (knl_H, T_LEAVE);
  985.  
  986.    return t;
  987. }
  988.